﻿using LxBasic;
using System.Collections.Generic;

namespace LxCore
{
    public abstract class FieldList
    {
        public abstract class Base<T> : FieldBase<T> where T : struct
        {
            public List<IField<T>> Fields = new();
            protected ICellVarArr<T>[] getCellVarArray(IIndexHost indexHost)
            {
                var fl = new ICellVarArr<T>[Fields.Count];
                for (int i1 = 0; i1 < fl.Length; i1++)
                {
                    fl[i1] = Fields[i1].GetCellVarArr(indexHost);
                }
                return fl;
            }
            protected IFaceVarArr<T>[] getFaceVarArray(IIndexHost indexHost)
            {
                var fl = new IFaceVarArr<T>[Fields.Count];
                for (int i1 = 0; i1 < fl.Length; i1++)
                {
                    fl[i1] = Fields[i1].GetFaceVarArr(indexHost);
                }
                return fl;
            }
        }
        public class Double : Base<double>
        {
            public override ICellVarArr<double> GetCellVarArr(IIndexHost indexHost)
            {
                return new CellVarArrayDouble() { Fields = getCellVarArray(indexHost) };
            }
            public override IFaceVarArr<double> GetFaceVarArr(IIndexHost indexHost)
            {
                return new FaceVarArrayDouble() { Fields = getFaceVarArray(indexHost) };
            }
            public override bool IsParameter(out double value)
            {
                value = 0;
                foreach (var l in Fields)
                {
                    if (l.IsParameter(out double vTemp))
                    {
                        value += vTemp;
                    }
                    else
                    {
                        return false;
                    }
                }
                return true;
            }
        }
        public class Vector : Base<Vector3d>
        {
            public override ICellVarArr<Vector3d> GetCellVarArr(IIndexHost indexHost)
            {
                return new CellVarArrayVector() { Fields = getCellVarArray(indexHost) };
            }
            public override IFaceVarArr<Vector3d> GetFaceVarArr(IIndexHost indexHost)
            {
                return new FaceVarArrayVector() { Fields = getFaceVarArray(indexHost) };
            }
            public override bool IsParameter(out Vector3d value)
            {
                value = Vector3d.Zero;
                foreach (var l in Fields)
                {
                    if (l.IsParameter(out Vector3d vTemp))
                    {
                        value += vTemp;
                    }
                    else
                    {
                        return false;
                    }
                }
                return true;
            }
        }
        public class CellVarArrayDouble : ICellVarArr<double>
        {
            public ICellVarArr<double>[] Fields;
            public double GetCellVar(int cellID)
            {
                double r = 0;
                foreach (var f in Fields)
                {
                    r += f.GetCellVar(cellID);
                }
                return r;
            }
        }
        public class FaceVarArrayDouble : IFaceVarArr<double>
        {
            public IFaceVarArr<double>[] Fields;
            public double GetFaceVar(int faceID)
            {
                double r = 0;
                foreach (var f in Fields)
                {
                    r += f.GetFaceVar(faceID);
                }
                return r;
            }
        }
        public class CellVarArrayVector : ICellVarArr<Vector3d>
        {
            public ICellVarArr<Vector3d>[] Fields;
            public Vector3d GetCellVar(int cellID)
            {
                Vector3d r = new();
                foreach (var f in Fields)
                {
                    r += f.GetCellVar(cellID);
                }
                return r;
            }
        }
        public class FaceVarArrayVector : IFaceVarArr<Vector3d>
        {
            public IFaceVarArr<Vector3d>[] Fields;
            public Vector3d GetFaceVar(int faceID)
            {
                Vector3d r = new();
                foreach (var f in Fields)
                {
                    r += f.GetFaceVar(faceID);
                }
                return r;
            }
        }
    }
}
